﻿using DotNet.Utilities;
using JinfuyuanProject.Entity;
using JinfuyuanProject.Entity.ViewModels;
using JinfuyuanProject.Entity.Filter;
using JinfuyuanProject.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
using DocumentFormat.OpenXml.Office2010.Excel;

namespace JinfuyuanProject.Service
{
    public class ContractService : IContractService
    {
        private readonly IContractRepository _contractRepository;
        private readonly JinfuyuanDbContext _db;

        public ContractService(IContractRepository contractRepository, JinfuyuanDbContext db)
        {
            _contractRepository = contractRepository;
            _db = db;
        }
        #region 公共方法
        public bool Delete(Contract contract)
        {
            return _contractRepository.Delete(contract);
        }

        public IQueryable<Contract> GetList()
        {
            return _contractRepository.GetList();
        }

        public Contract GetModel(int Id)
        {
            return _contractRepository.GetModel(Id);
        }

        public int Insert(Contract contract)
        {
            return _contractRepository.Insert(contract);
        }

        public bool Update(Contract contract)
        {
            return _contractRepository.Update(contract);
        }
        #endregion
        #region 业务方法
        public ResMessage UpdataContract(ParturientContractVM pcvm)
        {
            using (var transaction = _db.Database.BeginTransaction())
            {
                // 查询合同信息
                var contract = _db.Contract
                    .FirstOrDefault(x => x.ContractNumber == pcvm.ContractNumber);
                if (contract == null)
                    return ResMessage.Fail("合同不存在");
                // 查询产妇信息
                var parturient = _db.Parturient
                    .FirstOrDefault(x => x.Id == pcvm.Id);
                if (parturient == null)
                    return ResMessage.Fail("产妇信息不存在");
                // 查询房间信息
                var home = _db.Home
                    .FirstOrDefault(x => x.Id == pcvm.HomeId);
                if (home == null)
                    return ResMessage.Fail("房间信息不存在");
                try
                {
                    // 更新合同信息
                    contract.HomeId = pcvm.HomeId;
                    contract.LiveTime = pcvm.LiveTime;
                    // 更新产妇信息
                    parturient.HomeId = pcvm.HomeId;
                    // 更新房间信息
                    home.State = 1;
                    _db.SaveChanges();
                    transaction.Commit();
                    return ResMessage.Success();
                }
                catch (Exception ex)
                {
                    // 如果发生异常，则回滚事务
                    transaction.Rollback();
                    return ResMessage.Fail(ex.Message);
                }
            }

        }
        //合同支付成功
        public ResMessage PaySuccess(int cId, decimal PayMoney, int sid,int PayWay)
        {

            using (var transaction = _db.Database.BeginTransaction())  // 开启数据库事务
            {
                try
                {
                    // 修改合同表的订单状态
                    Contract contract = GetModel(cId);
                    if (contract == null)
                    {
                        return ResMessage.Fail("合同未找到");
                    }
                    contract.PayState = 1;
                    contract.PayWay = PayWay; 
                    // 财务表中插入一条记录
                    Entry entry = new Entry
                    {
                        ContractId = cId,
                        Describe = "客户套餐和押金支付",
                        EntryPrice = PayMoney,
                        Verify = 0,
                        CreateTime = DateTime.Now,
                        VerifyId = 0,
                        IsDelete = 0,
                        EntryPeopleId = sid,
                        FounderId = sid,
                        Type = 1
                    };
                  
                    _db.Entry.Add(entry); // 添加财务记录
                    // 产生员工绩效
                    int? sId = contract.EmpId; // 得到业务员的id 
                    if (sId == 0 || sId == null)
                    {
                        _db.SaveChanges();
                        transaction.Commit();
                        // 没有业务员，不计算绩效
                        return ResMessage.Success();
                    }
                    int Rid = Convert.ToInt32(_db.Staff.Where(x => x.Id == sId).Select(x => x.RoleId).FirstOrDefault());
                    decimal Proportion = _db.Role.Where(x => x.Id == Rid).Select(x => x.Proportion).FirstOrDefault().GetValueOrDefault();
                    decimal pmoney = contract.Money; // 套餐金额
                    decimal performanceAmount = pmoney * (Proportion / 100); // 计算绩效金额
                    SalaryDetails salaryDetails = new SalaryDetails();
                    salaryDetails.SalaryId = 0;
                    salaryDetails.ContractId = cId;
                    salaryDetails.Money = pmoney;
                    salaryDetails.Proportion = Proportion;
                    salaryDetails.CreateTime = DateTime.Now;
                    salaryDetails.CommissionMoney = performanceAmount;
                    _db.SalaryDetails.Add(salaryDetails); // 添加绩效记录
                    _db.SaveChanges();
                    // 提交事务
                    transaction.Commit();

                    return ResMessage.Success();
                }
                catch (Exception ex)
                {
                    // 如果发生异常，则回滚事务
                    transaction.Rollback();
                    return ResMessage.Fail($"支付失败: {ex.Message}");
                }
            }
        }

        public Hashtable GetPay(int id)
        {
            Hashtable ht = new Hashtable();
            ContractVM contract = _db.Database.SqlQuery<ContractVM>($"select p.ParturientName,p.ParturientPhone,h.Name,h.State,p.Deposit,a.PackageName,a.PackagePrice, c.* from Contract c inner join Parturient p on c.ParturientId=p.Id inner join Home h on c.HomeId=h.Id inner join Package a on c.PackageId=a.Id where c.Id={id}").FirstOrDefault();
            //ContractVM contract = contractVM.Where(x=>x.Id==id).FirstOrDefault();
            if (contract == null)
                ht["code"] = 1;
            ht["code"] = 0;
            ht["data"] = contract;
            return ht;
        }
        //过滤方法
        public Hashtable Query(ContractFilter contractFilter)
        {
            int count;
            IQueryable<ContractVM> contractvmList = _db.Database.SqlQuery<ContractVM>("select p.ParturientName,p.ParturientPhone,h.Name,h.State,c.Deposit,a.PackageName, c.* from Contract c inner join Parturient p on c.ParturientId=p.Id inner join Home h on c.HomeId=h.Id inner join Package a on c.PackageId=a.Id").AsQueryable();
            Hashtable hashtable = new Hashtable();
            hashtable["code"] = 0;
            hashtable["message"] = "success";
            hashtable["data"] = MakeQueryFilter(contractvmList, contractFilter, out count);
            hashtable["count"] = count;//结束惰性加载
            return hashtable;
        }
        public IQueryable<ContractVM> MakeQueryFilter(IQueryable<ContractVM> contractvmList, ContractFilter contractFilter, out int count)
        {

            if (!string.IsNullOrEmpty(contractFilter.ParturientName))
            {
                contractvmList = contractvmList.Where(x => x.ParturientName.Contains(contractFilter.ParturientName));
            }
            if (!string.IsNullOrEmpty(contractFilter.ParturientPhone))
            {
                contractvmList = contractvmList.Where(x => x.ParturientPhone.Contains(contractFilter.ParturientPhone));
            }
            if (contractFilter.PackageID != 0)
            {
                contractvmList = contractvmList.Where(x => x.PackageId == contractFilter.PackageID);
            }
            //需要过滤后没做分页前的所有数据条数
            count = contractvmList.Count();
            //做分页
            if (contractFilter.page != 0 && contractFilter.limit != 0)
                return contractvmList.OrderBy(x => x.Id).Skip((contractFilter.page - 1) * contractFilter.limit).Take(contractFilter.limit);
            else
                return contractvmList;
        }
        #endregion

    }
}
